package uk.ac.cam.echo.security;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import uk.ac.cam.echo.messages.Message;
import uk.ac.cam.echo.messages.SecurityMessage;
import uk.ac.cam.echo.security.SafeMessageQueue;

/**
 * @author Tom Smith
 */
public class DBSecurity {

	public static final SimpleDateFormat DateFormat = new SimpleDateFormat("[dd/MM/yy HH:mm:ss]");
	public static final SimpleDateFormat ShortDateFormat = new SimpleDateFormat("[HH:mm:ss]");
	
	private static DBSecurity Instance;
	/**
	 * @return The instance of DBInt.
	 */
	public static DBSecurity getInstance() {
		return DBSecurity.Instance;
	}
	/**
	 * Initialize and return the instance of DBInt.
	 * @param rfid The user's RFID.
	 * @param facebookID The user's facebookID
	 * @param host The host to connect to.
	 * @param port The port number to connect to.
	 * @return The instance of DBInt.
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	public static DBSecurity getInstance(String host, int port) throws UnknownHostException, IOException {
		if (DBSecurity.Instance == null) {
			DBSecurity.Instance = new DBSecurity(host, port);
		}
		return DBSecurity.getInstance();
	}
	
	
	private final Reader m_Reader;

	private final SafeMessageQueue<Message> m_SafeMessageQueue = new SafeMessageQueue<Message>();

	private final Socket m_Socket;
	
	private final Writer m_Writer;
	
	/**
	 * Initialize the class with the user's RFID, host, and port number to connect to.
	 * @param rfid The user's RFID.
	 * @param facebookID The user's facebookID
	 * @param host The host to connect to.
	 * @param port The port number to connect to.
	 * @throws UnknownHostException
	 * @throws IOException
	 */
	private DBSecurity(String host, int port) throws UnknownHostException, IOException {

		this.m_Socket = new Socket(host, port);

		this.m_Reader = new Reader(this.m_Socket);
		Thread readThread = new Thread(this.m_Reader);
		readThread.setDaemon(true);
		readThread.start();

		this.m_Writer = new Writer(this.m_Socket, this.m_SafeMessageQueue);
		Thread writeThread = new Thread(this.m_Writer);
		writeThread.setDaemon(true);
		writeThread.start();
	}

	/**
	 * Gets the security details for the user.
	 * @param userRFID The user RFID being checked.
	 * @return A SecurityMessage relating to the user.
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public synchronized SecurityMessage getSecurityDetails(String userRFID) throws IOException, InterruptedException {
		sendMessage(new SecurityMessage(userRFID));
		
		return (SecurityMessage) this.m_Reader.getMessage();
	}
	
	/**
	 * Puts a message on the queue to send to the client.
	 * @param m The message to be sent.
	 * @throws IOException
	 */
	private void sendMessage(Message m) throws IOException {
		this.m_SafeMessageQueue.put(m);
	}

}
